在昨天的文章中,我們成功使用 n8n 的 HTTP Request 節點跨越 Docker 容器邊界,調用了在本地運行的 FastAPI 推薦端點,驗證了微服務與工作流之間的資料流轉。
然而,昨天的測試資料是我們手動「寫死(Hardcode)」在 Set 節點裡的結構化 JSON。在真實應用中,使用者通常只會隨口說一句:
「我人在板橋,預算抓 300 左右,下午想找間安靜的甜點店吃蛋糕,有推薦的嗎?」
傳統程式很難直接從這段口語中拆解出 location、budget_max 或 cuisine。這時候,就是我們在 Day 02 設定好的 Dify + Google Gemini 大腦登場的最佳時機!
今天 Day 07,我們將學習如何在 Dify 中發布 API,並在 n8n 中調用 Dify,把一段自然語言口語,自動轉換為標準結構化 JSON 參數!
今天我們要完成的鏈路如下:
[使用者自然語言輸入]
│
▼
[n8n 工作流 (Trigger)]
│
▼ (HTTP POST)
[Dify API + Gemini 3.5 Flash-Lite] <-- AI 意圖辨識 & JSON 參數提取
│
▼ (回傳標準 JSON)
[n8n 提取參數]
│
▼ (HTTP POST host.docker.internal:8000)
[FastAPI 推薦端點 (/api/v1/recommend/)]
│
▼
[產出推薦餐廳結果]
首先我們要讓 Dify 扮演「資訊抽取器(Information Extractor)」,並開啟對外 API 存取權限。
1.打開瀏覽器進入 Dify 介面(http://localhost)。
2.進入「工作室」➜「建立空白應用」。
3.選擇「聊天助手(Chatbot)」,名稱填寫 美食意圖抽取器。
在應用編排頁面的 指令 / 系統提示詞(System Prompt) 欄位中,填入嚴格要求輸出 JSON 的結構指令:
你是一個專業的美食推薦助理前置解析器。你的任務是從使用者的自然語言對話中,精準提取推薦條件,並「只輸出 JSON 格式」,不要包含任何額外問候或 Markdown 語法標籤。
請提取以下欄位:
- cuisine: 料理類型(必須是以下之一:日式、韓式、台式、甜點/下午茶、咖啡廳、西式、全部)
- budget_max: 每人預算上限(整數數字,若未提及預設為 500)
- location: 地區或捷運站商圈(字串,若未提及預設為「板橋區」)
- notes: 特殊飲食需求或關鍵字(字串,若無則為空字串)
輸出範例格式:
{
"cuisine": "甜點/下午茶",
"budget_max": 300,
"location": "板橋",
"notes": "想吃蛋糕、安靜"
}
模型確認:確認模型選用之前驗證成功的 Gemini 3.5 Flash-Lite,反應迅速且不會塞車!
1.在應用編排畫面的左側選單中,點選 「訪問 API」(Access API)。
2.點擊右上角的 「API 密鑰」(API Keys)➜ 「建立密鑰」。
3.複製生成的 API Key(格式通常為 app-xxxxxxxxxxxxxxxx)。
4.同時記下畫面上顯示的 API 基礎網址,本地部署預設為:
http://localhost/v1
提醒:在 n8n 容器內連線時,同樣要轉換為 http://host.docker.internal/v1 哦!
切換到 n8n(http://localhost:5678),打開昨天的推薦工作流或建立一個新流程。
使用 Edit Fields (Set) 模擬使用者真實的對話輸入:
欄位名稱:user_message
數值內容:我人在板橋,預算抓 300 左右,下午想找間安靜的甜點店吃蛋糕,有推薦的嗎?
1.新增一個 HTTP Request 節點,命名為 Call Dify AI。
2.配置參數如下:
Method:POST
URL:http://host.docker.internal/v1/chat-messages
Authentication:Header Auth
Name:Authorization
Value:Bearer <你的_DIFY_APP_API_KEY>
Send Headers:Content-Type: application/json
Send Body:開啟(Toggle On)
Body Content Type:JSON
Specify Body:選擇 Using JSON
JSON 內容:
{
"inputs": {},
"query": "={{ $json.user_message }}",
"response_mode": "blocking",
"user": "ironman_tester"
}
這裡使用 "response_mode": "blocking" 代表等待整段完成後一次回傳,方便程式直接解析。
Dify 回傳的結果會放在 $json.answer 字串中。我們新增一個 Code 節點,將文字解析為真正的 JSON 物件:
1.點擊 + 新增 Code 節點(命名為 Parse AI JSON)。
2.語言選擇 JavaScript,填入以下程式碼:
// 取得 Dify 回傳的純文字內容
let rawAnswer = $input.first().json.answer;
// 去除可能夾帶的 Markdown 標記 (如 ```json 或 ```)
rawAnswer = rawAnswer.replace(/```json/g, '').replace(/```/g, '').trim();
// 解析為 JSON 物件
let parsedData = JSON.parse(rawAnswer);
// 將 user_id 補齊,並回傳給下一個節點
return {
user_id: "line_user_888",
cuisine: parsedData.cuisine || "全部",
budget_max: parsedData.budget_max || 500,
location: parsedData.location || "板橋區",
notes: parsedData.notes || ""
};
將 Parse AI JSON 節點後方直接連線至昨天的 HTTP Request (Call FastAPI) 節點:
URL 保持:http://host.docker.internal:8000/api/v1/recommend/
Request Body 欄位直接繼承上一步解析出來的參數:
user_id:{{ $json.user_id }}
cuisine:{{ $json.cuisine }}
budget_max:{{ $json.budget_max }}
location:{{ $json.location }}
notes:{{ $json.notes }}
點擊 n8n 畫布下方的 Test workflow 按鈕執行完整流程:
1.Dify 辨識:Dify 與 Gemini 成功接收到使用者的口語句子,並輸出:
{
"cuisine": "甜點/下午茶",
"budget_max": 300,
"location": "板橋",
"notes": "蛋糕、安靜"
}
2.Code 節點解析:成功轉化為乾淨的 JSON 欄位。
3.FastAPI 計算:FastAPI 後端接收到精確參數,自動過濾出符合條件的餐廳(恬淡日常法式甜點)。
4.輸出結果:最終成功產生格式化推薦小卡!
今日結語與明日預告
今天我們正式將 LLM 自然語言理解力 與 工程化的微服務系統 成功融合!現在你的系統已經不再需要依賴僵硬的表單或指令,而是能真正「聽懂」使用者的日常需求並觸發相對應的後端運算。
目前整體系統架構:
口語輸入 ➜ n8n ➜ Dify (Gemini 大腦抽取) ➜ FastAPI (資料庫與商業篩選) ➜ n8n 格式化輸出
明天 Day 08,我們將邁向使用者觸達的重要里程碑:建立 LINE Messaging API 開發者帳號與 Channel 設定,把我們的 AI Agent 帶到最親民的手機聊天室! 敬請期待!